home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / src / kant-generator-04-c / Kant ƒ / Shell ƒ / prefs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-23  |  10.3 KB  |  385 lines  |  [TEXT/MMCC]

  1. #include "program globals.h"
  2. #include "prefs.h"
  3. #include "help.h"
  4. #include "dialogs.h"
  5. #include "environment.h"
  6. #include "util.h"
  7. #include "Folders.h"
  8.  
  9. #define        PREFS_FILE_NAME            "\pKant Generator prefs"
  10. #define        PREFS_TYPE                'pref'
  11. // CREATOR is #defined in "program globals.h"
  12. #define        PREFS_HEADER_VERSION    1
  13.  
  14. Str255            gMyName;
  15. Str255            gMyOrg;
  16.  
  17. typedef struct
  18. {
  19.     long            fileID;
  20.     short            maintopic;
  21.     short            subtopic;
  22.     
  23.     char            regname[40];
  24.     char            regorg[40];
  25.     Boolean            alwaysResolve;
  26.     Boolean            unused;
  27.     short            speedDelay;
  28. } PrefStruct;
  29.  
  30. /* internal globals for use in prefs.c only */
  31. static long            gFileID;
  32. static Boolean        gCanSavePrefs;
  33. static PrefStruct    thePrefs;
  34. static long            gPrefsFilePos;
  35.  
  36. /*-----------------------------------------------------------------------------------*/
  37. /* internal stuff for prefs.c                                                        */
  38.  
  39. enum PrefErrorTypes OpenPrefsFile(short *prefsFileID);
  40. enum PrefErrorTypes SetupNewPrefsFile(short prefsFileID);
  41. void ClosePrefsFile(short prefsFileID);
  42. enum PrefErrorTypes GetNextPrefs(short prefsFileID);
  43. enum PrefErrorTypes SavePrefs(short prefsFileID);
  44. enum PrefErrorTypes CheckVersion(short prefsFileID);
  45. enum PrefErrorTypes GetFileID(void);
  46. enum PrefErrorTypes CheckFileID(void);
  47. enum PrefErrorTypes Virgin(short prefsFileID);
  48. void DefaultPrefs(void);
  49. void CopyGlobalsToPrefs(void);
  50. void CopyPrefsToGlobals(void);
  51. void GetRegistration(void);
  52.  
  53. void SaveThePrefs(void)
  54. /* standard procedure callable from anywhere to save prefs to disk (if possible) */
  55. {
  56.     short            prefsFileID;
  57.     
  58.     if (gCanSavePrefs)        /* if we had no errors in PreferencesInit() */
  59.     {
  60.         OpenPrefsFile(&prefsFileID);    /* open the prefs file */
  61.         CopyGlobalsToPrefs();            /* copy global variables to prefs struct */
  62.         SavePrefs(prefsFileID);            /* save prefs to disk */
  63.         ClosePrefsFile(prefsFileID);    /* close prefs file */
  64.     }
  65. }
  66.  
  67. enum PrefErrorTypes PreferencesInit(void)
  68. {
  69.     short            prefsFileID;
  70.     enum PrefErrorTypes        err;
  71.     
  72.     gCanSavePrefs=FALSE;    /* assume the worst and maybe you'll be pleasantly surprised */
  73.     err=GetFileID();        /* get application file ID */
  74.     if (err!=prefs_allsWell)    /* screwed up already?!? */
  75.         return err;
  76.     
  77.     err=OpenPrefsFile(&prefsFileID);    /* open prefs file (or create new one) */
  78.     if (err!=prefs_allsWell)
  79.     {
  80.         if ((err==prefs_diskReadErr) || (err==prefs_diskWriteErr) || (err==prefs_virginErr))
  81.             ClosePrefsFile(prefsFileID);    /* close & abort if error or if new prefs */
  82.         return err;
  83.     }
  84.     
  85.     err=CheckVersion(prefsFileID);        /* check prefs version */
  86.     if (err!=prefs_allsWell)
  87.     {
  88.         ClosePrefsFile(prefsFileID);
  89.         return err;
  90.     }
  91.     
  92.     GetFPos(prefsFileID, &gPrefsFilePos);
  93.     gPrefsFilePos-=sizeof(thePrefs);
  94.     do
  95.     {
  96.         gPrefsFilePos+=sizeof(thePrefs);
  97.         err=GetNextPrefs(prefsFileID);        /* get prefs struct from file */
  98.         if (err==prefs_noMorePrefsErr)        /* or not */
  99.             return (Virgin(prefsFileID));    /* can't find our file ID, it's our first time */
  100.         
  101.         if (err!=prefs_allsWell)            /* any other error, just abort */
  102.         {
  103.             ClosePrefsFile(prefsFileID);
  104.             return err;
  105.         }
  106.         
  107.         err=CheckFileID();                    /* check file ID of current prefs struct */
  108.     }
  109.     while (err==prefs_IDNotMatchErr);
  110.     
  111.     CopyPrefsToGlobals();                    /* copy prefs struct to program globals */
  112.     ClosePrefsFile(prefsFileID);            /* close prefs file */
  113.     
  114.     return prefs_allsWell;                    /* piece o' cake */
  115. }
  116.  
  117. void PrefsError(enum PrefErrorTypes err)
  118. {
  119.     Str255            tempStr;
  120.     
  121.     switch (err)
  122.     {
  123.         case prefs_diskReadErr:
  124.         case prefs_diskWriteErr:
  125.         case prefs_cantCreatePrefsErr:
  126.         case prefs_cantOpenPrefsErr:
  127.         case prefs_versionNotSupportedErr:
  128.             DefaultPrefs();                    /* use default prefs if error */
  129.             gCanSavePrefs=FALSE;            /* don't bother trying to save prefs later */
  130.             GetIndString(tempStr, 128, err);    /* get error string from .rsrc file */
  131.             ParamText(tempStr, "\p", "\p", "\p");
  132.             PositionDialog('ALRT', largeAlert);
  133.             StopAlert(largeAlert, 0L);        /* display error alert */
  134.             break;
  135.         default:
  136.             gCanSavePrefs=TRUE;                /* can save prefs to disk later if needed */
  137.             break;
  138.     }
  139. }
  140.  
  141. enum PrefErrorTypes OpenPrefsFile(short *prefsFileID)
  142. {
  143.     short            thisFile;
  144.     Boolean            newPrefs;
  145.     unsigned char    *name=PREFS_FILE_NAME;
  146.     OSErr            isHuman;
  147.     short            vRefNum;
  148.     long            dirID;
  149.     FSSpec            prefsFile;
  150.     
  151.     newPrefs=FALSE;
  152.     /* find vRefNum and dirID of preferences folder, creating it if necessary */
  153.     isHuman=FindFolder(kOnSystemDisk, 'pref', kCreateFolder, &vRefNum, &dirID);
  154.     
  155.     if (isHuman!=noErr)        /* screwed up already?!? */
  156.         return prefs_cantOpenPrefsErr;
  157.     
  158.     isHuman=FSMakeFSSpec(vRefNum, dirID, name, &prefsFile);    /* make FSSpec out of it */
  159.     if (isHuman!=noErr)
  160.     {
  161.         if (isHuman==fnfErr)    /* FSSpec is valid, but prefs file does not exist */
  162.         {
  163.             isHuman=FSpCreate(&prefsFile, CREATOR, PREFS_TYPE, 0);    /* so create it */
  164.             if (isHuman!=noErr)                                        /* or not */
  165.                 return prefs_cantCreatePrefsErr;
  166.             newPrefs=TRUE;        /* signal that prefs file is new */
  167.         }
  168.         else return prefs_cantOpenPrefsErr;
  169.     }
  170.     isHuman=FSpOpenDF(&prefsFile, fsRdWrPerm, &thisFile);    /* open prefs file */
  171.     *prefsFileID=thisFile;        /* store file reference number */
  172.     if (isHuman!=noErr)
  173.         return prefs_cantOpenPrefsErr;
  174.     
  175.     if (newPrefs)
  176.         return SetupNewPrefsFile(*prefsFileID);        /* needs initial setup if new */
  177.     
  178.     return prefs_allsWell;
  179. }
  180.  
  181. enum PrefErrorTypes SetupNewPrefsFile(short prefsFileID)
  182. /* this writes the prefs version number to the newly created prefs file, so we can
  183.    tell if the prefs file was created by a later version of the program and is
  184.    therefore in a format that we don't support -- forward compatability!  what
  185.    a concept! */
  186. {
  187.     long            count;
  188.     short            temp;
  189.     
  190.     gPrefsFilePos=2L;
  191.     if (SetEOF(prefsFileID, 2L)!=noErr)    /* set length of prefs file to 2 */
  192.         return prefs_diskWriteErr;
  193.     
  194.     SetFPos(prefsFileID, 1, 0L);
  195.     temp=PREFS_HEADER_VERSION;            /* get the prefs version (hardcoded) */
  196.     count=2L;
  197.     if (FSWrite(prefsFileID, &count, &temp)!=noErr)        /* write prefs version */
  198.         return prefs_diskWriteErr;        
  199.     
  200.     return Virgin(prefsFileID);            /* be gentle; it's our first time */
  201. }
  202.  
  203. void ClosePrefsFile(short prefsFileID)
  204. {
  205.     FSClose(prefsFileID);                /* close file on disk */
  206.     FlushVol(0L, kOnSystemDisk);        /* flush volume to write out new info */
  207. }
  208.  
  209. enum PrefErrorTypes GetNextPrefs(short prefsFileID)
  210. {
  211.     OSErr        isHuman;
  212.     long        count;
  213.     
  214.     count=sizeof(thePrefs);
  215.     isHuman=FSRead(prefsFileID, &count, &thePrefs);        /* get next prefs struct */
  216.     if (isHuman==eofErr)    /* no more left */
  217.         return prefs_noMorePrefsErr;
  218.     if (isHuman!=noErr)        /* some other error */
  219.         return prefs_diskReadErr;
  220.     
  221.     return prefs_allsWell;
  222. }
  223.  
  224. enum PrefErrorTypes SavePrefs(short prefsFileID)
  225. {
  226.     long        oldEOF;
  227.     long        count;
  228.     
  229.     GetEOF(prefsFileID, &oldEOF);
  230.     if (gPrefsFilePos>=oldEOF)        /* add new prefs struct onto end of prefs file */
  231.     {
  232.         if (SetEOF(prefsFileID, oldEOF+sizeof(thePrefs))!=noErr)
  233.             return prefs_diskWriteErr;
  234.     }
  235.     
  236.     SetFPos(prefsFileID, 1, gPrefsFilePos);        /* set position inside prefs file */
  237.     count=sizeof(thePrefs);
  238.     /* write prefs struct and return appropriate error code */
  239.     return (FSWrite(prefsFileID, &count, &thePrefs)!=noErr) ?
  240.         prefs_diskWriteErr : prefs_allsWell;
  241. }
  242.  
  243. enum PrefErrorTypes CheckVersion(short prefsFileID)
  244. {
  245.     OSErr        isHuman;
  246.     long        count;
  247.     short            temp;
  248.     
  249.     count=2L;
  250.     isHuman=FSRead(prefsFileID, &count, &temp);        /* get prefs version */
  251.     if (isHuman!=noErr)
  252.         return prefs_diskReadErr;
  253.     if (temp>PREFS_HEADER_VERSION)                    /* too new */
  254.         return prefs_versionNotSupportedErr;
  255.     if (temp<PREFS_HEADER_VERSION)                    /* old; overwrite */
  256.         return SetupNewPrefsFile(prefsFileID);
  257.     
  258.     return prefs_allsWell;
  259. }
  260.  
  261. enum PrefErrorTypes GetFileID(void)
  262. {
  263.     ParamBlockRec    pb;
  264.     
  265.     pb.fileParam.ioCompletion=0L;
  266.     pb.fileParam.ioNamePtr=LMGetCurApName();
  267.     pb.fileParam.ioVRefNum=0;
  268.     pb.fileParam.ioFVersNum=0;
  269.     pb.fileParam.ioFDirIndex=0;
  270.     if (PBGetFInfo(&pb, FALSE)!=noErr)
  271.         return prefs_diskReadErr;
  272.     
  273.     gFileID=pb.fileParam.ioFlNum;
  274.     
  275.     return prefs_allsWell;
  276. }
  277.  
  278. enum PrefErrorTypes CheckFileID(void)
  279. {
  280.     /* compare file ID in current prefs struct to application's file ID */
  281.     return (thePrefs.fileID==gFileID) ? prefs_allsWell : prefs_IDNotMatchErr;
  282. }
  283.  
  284. enum PrefErrorTypes Virgin(short prefsFileID)
  285. {
  286.     enum PrefErrorTypes    err;
  287.     
  288.     DefaultPrefs();
  289.     CopyGlobalsToPrefs();
  290.     err=SavePrefs(prefsFileID);
  291.     if (err!=prefs_allsWell)
  292.         return err;
  293.     GetRegistration();
  294.     CopyGlobalsToPrefs();
  295.     err=SavePrefs(prefsFileID);
  296.     
  297.     return (err==prefs_allsWell) ? prefs_virginErr : err;
  298. }
  299.  
  300. void DefaultPrefs(void)
  301. {
  302.     unsigned char        *bob="\pBob";
  303.     
  304.     gMainTopicShowing=gSubTopicShowing=0;
  305.     
  306.     Mymemcpy((Ptr)gMyName, (Ptr)bob, bob[0]+1);
  307.     gMyOrg[0]=0x00;
  308.     
  309.     gAlwaysResolve=TRUE;
  310.     gSpeedDelay=0;
  311. }
  312.  
  313. void CopyGlobalsToPrefs(void)
  314. {
  315.     Mymemset((Ptr)(&thePrefs), 0, sizeof(thePrefs));
  316.     if (gMyName[0]>0x27)
  317.         gMyName[0]=0x27;
  318.     if (gMyOrg[0]>0x27)
  319.         gMyOrg[0]=0x27;
  320.     Mymemcpy((Ptr)thePrefs.regname, (Ptr)gMyName, gMyName[0]+1);
  321.     Mymemcpy((Ptr)thePrefs.regorg, (Ptr)gMyOrg, gMyOrg[0]+1);
  322.     thePrefs.maintopic=gMainTopicShowing;
  323.     thePrefs.subtopic=gSubTopicShowing;
  324.     thePrefs.fileID=gFileID;
  325.     
  326.     thePrefs.alwaysResolve=gAlwaysResolve;
  327.     thePrefs.speedDelay=gSpeedDelay;
  328. }
  329.  
  330. void CopyPrefsToGlobals(void)
  331. {
  332.     Mymemcpy((Ptr)gMyName, (Ptr)thePrefs.regname, thePrefs.regname[0]+1);
  333.     Mymemcpy((Ptr)gMyOrg, (Ptr)thePrefs.regorg, thePrefs.regorg[0]+1);
  334.     gMainTopicShowing=thePrefs.maintopic;
  335.     gSubTopicShowing=thePrefs.subtopic;
  336.     
  337.     gAlwaysResolve=thePrefs.alwaysResolve;
  338.     gSpeedDelay=thePrefs.speedDelay;
  339. }
  340.  
  341. void GetRegistration(void)
  342. {
  343.     DialogPtr        theDlog;
  344.     short            itemSelected = 0;
  345.     short            newleft;
  346.     short            newtop;
  347.     short            itemType;
  348.     Handle            item;
  349.     Rect            box;
  350.     
  351.     theDlog = GetNewDialog(131, 0L, (WindowPtr)-1L);
  352.     newleft = qd.screenBits.bounds.left + (((qd.screenBits.bounds.right -
  353.                 qd.screenBits.bounds.left) - (theDlog->portRect.right -
  354.                 theDlog->portRect.left)) / 2);
  355.     newtop = qd.screenBits.bounds.top + (((qd.screenBits.bounds.bottom -
  356.                 qd.screenBits.bounds.top) - (theDlog->portRect.bottom -
  357.                 theDlog->portRect.top)) / 2);
  358.     if(newtop < 15)
  359.         newtop = 15;
  360.     GetDItem(theDlog, 1, &itemType, &item, &box);
  361.     InsetRect(&box, -4, -4);
  362.     SetDItem(theDlog, 8, userItem, (Handle)OutlineDefaultButton, &box);
  363.     ParamText(APPLICATION_NAME, "\p", "\p", "\p");
  364.     
  365.     MoveWindow(theDlog, newleft, newtop, TRUE);
  366.     ShowWindow(theDlog);
  367.     while(itemSelected != 1)
  368.     {
  369.         ModalDialog(0L, &itemSelected);
  370.     }
  371.     GetDItem(theDlog,4,&itemType,&item,&box);
  372.     GetIText(item,gMyName);
  373.     
  374.     GetDItem(theDlog,5,&itemType,&item,&box);
  375.     GetIText(item,gMyOrg);
  376.  
  377.     if (gMyName[0]==0x00)
  378.         DefaultPrefs();
  379.  
  380.     HideWindow(theDlog);
  381.     DisposeDialog(theDlog);
  382.     
  383.     gIsVirgin=TRUE;
  384. }
  385.